Skip to content

Skip no-op slice timing correction when timing metadata is absent#294

Merged
nx10 merged 2 commits into
mainfrom
impl/slice-time-noop-skip
Apr 12, 2026
Merged

Skip no-op slice timing correction when timing metadata is absent#294
nx10 merged 2 commits into
mainfrom
impl/slice-time-noop-skip

Conversation

@nx10
Copy link
Copy Markdown
Contributor

@nx10 nx10 commented Apr 9, 2026

When a BOLD run has no SliceTiming in the BIDS sidecar, slice_timing_correction was still calling 3dTshift, which would inspect the NIfTI header, find no timing info, and produce a "dataset is already aligned in time" warning before copying the input unchanged.

This PR:

  • Adds a NIfTI header fallback for slice timing in FunctionalMetadata.load(), matching the existing TR resolution pattern (sidecar > header)
  • Skips the 3dTshift call entirely when neither source provides timing info
  • Logs the source of slice timing at each level (info for sidecar, warning for header fallback, warning for skip)

Closes #262

@nx10 nx10 requested review from jpillai00 and kaitj April 9, 2026 22:40
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 9, 2026

Coverage

Coverage Report
FileStmtsMissCoverMissing
rbc
   __init__.py10100% 
   context.py25868%70, 75–77, 79–80, 93–94
   metadata.py670100% 
rbc/bids
   __init__.py90100% 
   _schema.py585499%776, 782, 790, 1101
   anatomical.py24387%44, 47–48
   builder.py72790%233–235, 362, 364–365, 386
   functional.py42588%46–49, 84
   longitudinal.py250100% 
   metrics.py23195%44
   qc.py170100% 
   query.py674237%103–107, 121–125, 127–128, 130–135, 137, 139, 153, 159–165, 198, 207, 209–216, 225, 257, 266–267
   session.py470100% 
rbc/cli
   __init__.py10100% 
   all.py49295%84, 109
   anatomical.py25292%47, 63
   base.py71987%56, 62, 123–125, 131–133, 156
   functional.py33293%67, 87
   longitudinal.py27292%46, 63
   main.py420100% 
   metrics.py42295%77, 95
   qc.py25292%45, 61
rbc/core
   __init__.py30100% 
   common.py261253%43–45, 62–70
   fileops.py27485%69–72
   fsl2itk.py420100% 
   nifti.py192597%236–237, 244–245, 524
   niwrap.py56198%58
rbc/core/anatomical
   __init__.py40100% 
   registration.py15473%59, 151, 166, 183
   segmentation.py24866%64, 74–76, 92, 114, 125, 141
rbc/core/functional
   __init__.py130100% 
   coregistration.py7271%44, 55
   despiking.py7357%32, 36–37
   distortion.py1304069%269–271, 321, 324, 332–335, 341–346, 349, 352–353, 356, 365–369, 375–376, 387–388, 391, 397, 443–444, 447, 455, 461, 470–471, 474, 484, 491
   erosion.py32196%50
   initialization.py9455%35, 42–43, 63
   masking.py342526%53, 55–56, 58–59, 62–65, 69, 91, 134, 183, 197, 208, 223, 233, 249, 258, 271, 285, 296, 306, 319, 328
   motion.py573735%62, 64–67, 69, 71, 73, 76–77, 83–84, 86–87, 95–97, 99, 102, 105, 107, 124–125, 135–138, 159, 169, 171–172, 175, 177–179, 181, 183
   nuisance.py816025%78, 80–85, 87, 89–90, 93, 96–98, 100–102, 104–110, 112–116, 118, 163, 165, 167, 170–171, 173–175, 178, 181–182, 185–187, 190–193, 197, 203–205, 207, 235, 243, 269, 278, 307, 316, 322
   regressors.py89693%163, 193, 325–328
   resampling.py544320%37–42, 74–76, 78, 80–81, 85–87, 90, 93, 105, 107–108, 112, 114, 150–152, 154–155, 159, 161–162, 167–169, 173–174, 177, 180, 187, 199, 201–202, 207, 209
   timing.py161131%46–47, 49–53, 58, 60, 66–67
rbc/core/longitudinal
   __init__.py10100% 
   transform.py46784%106–107, 165–168, 170
rbc/core/metrics
   __init__.py30100% 
   alff.py90198%265
   reho.py660100% 
   smoothing.py7357%36, 42–43
   standardization.py271159%64, 66–68, 70, 72–75, 77–78
   timeseries.py70198%147
rbc/core/qc
   __init__.py60100% 
   dvars.py260100% 
   motion.py310100% 
   registration.py410100% 
   xcp.py410100% 
rbc/orchestration
   __init__.py32293%90, 93
   all.py41978%131–132, 137, 145, 153–154, 171, 173–174
   anatomical.py372240%49–52, 57–58, 60–63, 85–87, 89–90, 94, 101, 104, 109–110, 116, 118
   functional.py411270%124–126, 128–129, 133, 139, 142, 147–148, 157, 159
   longitudinal.py56198%150
   metrics.py463034%32–35, 38–40, 67, 75–76, 100–102, 104–106, 110, 118–121, 123–124, 130–132, 137, 145, 152, 154
   qc.py340100% 
rbc/workflows
   __init__.py100100% 
   anatomical.py471959%90–93, 97–102, 107, 177–180, 182–184, 188
   functional.py1015941%113–114, 122, 127–128, 136, 207–208, 211–212, 215–216, 219, 222–225, 235–237, 247–248, 251, 254, 257–259, 265, 268, 272–273, 280–281, 288–289, 296–297, 300–302, 305–308, 320–321, 333, 335–338, 341–342, 351–352, 360, 367, 436, 442
   metrics.py411856%80, 83–84, 93–94, 99–102, 105–108, 112–115, 119
   qc.py553438%88–89, 92–93, 96, 99, 102–107, 110, 119–121, 125–128, 130–134, 136–137, 139–141, 144, 161, 167, 169
rbc_resources
   __init__.py380100% 
TOTAL327158682% 

Tests Skipped Failures Errors Time
733 0 💤 0 ❌ 0 🔥 10.179s ⏱️

@nx10 nx10 force-pushed the impl/slice-time-noop-skip branch from 367a29b to 5dc4dfa Compare April 10, 2026 06:50
Comment thread src/rbc/workflows/functional.py Outdated
@nx10 nx10 merged commit 6a2b68f into main Apr 12, 2026
8 checks passed
@nx10 nx10 deleted the impl/slice-time-noop-skip branch April 12, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Slice timing correction 3dTshift output dataset is just a copy of input dataset

2 participants